package cn.edu.sjtu.se.dslab.rhapsody.parse;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;

import cn.edu.sjtu.se.dslab.util.FileUtil;

public class XmiGenerator {
	private static final Logger logger = Logger.getLogger(XmiGenerator.class);
	private static final String XML_HREADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
	private XMLWriter writer;
	private Document document;
	private XmiBean xmiBean;

	public XmiGenerator(String relativePath, XmiBean xmiBean) {
		this.xmiBean = xmiBean;
		File xmiFile = new File( FileUtil.getRootPath() + relativePath);
		System.out.println(FileUtil.getRootPath() + relativePath);
		try {
			if(!xmiFile.exists()){
				xmiFile.createNewFile();
			}
			writer = new XMLWriter(new FileWriter(xmiFile));
		}catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void generate(){
		document = DocumentHelper.createDocument();
		document.setXMLEncoding("UTF-8");
		addXmiContent();
		try {
			writer.write(document);
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if (writer != null){
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private void addXmiContent(){
		Element rootElement = document.addElement(XmiConst.L_XMI_XMI.getQualifiedName());
		rootElement.addAttribute(XmiConst.A_XMI_VERSION, "2.1");
		//add namespace
		rootElement.add(XmiConst.XMI_NS);
		rootElement.add(XmiConst.XSI_NS);
		rootElement.add(XmiConst.ECORE_NS);
		rootElement.add(XmiConst.UML_NS);
		rootElement.addAttribute(XmiConst.A_XSI_SCHEMALOCATION, XmiConst.XSI_SCHEMALOCATION);
		
		
		for (UmlModel model: xmiBean.getUmlModels()){
			addUmlModel(rootElement, model);
		}
	}

	private void addUmlModel(Element rootElement, UmlModel model) {
		Element modelElement = rootElement.addElement(XmiConst.L_UML_MODEL);
		modelElement.addAttribute(XmiConst.A_XMI_ID, model.getId());
		modelElement.addAttribute(XmiConst.A_NAME, model.getName());
		for (XmiType type: model.getChildren()){
			addXmiType(modelElement, type);
		}
	}

	private void addXmiType(Element modelElement, XmiType type) {
		Element typeElement = 	modelElement.addElement(XmiConst.L_PACKAGED_ELEMENT);
		typeElement.addAttribute(XmiConst.A_XMI_TYPE, type.getXmiType());
		typeElement.addAttribute(XmiConst.A_XMI_ID, type.getXmiId());
		typeElement.addAttribute(XmiConst.A_NAME, type.getName());
	}

}
